﻿using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.HtmlControls;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Drawing;
using System.Drawing.Drawing2D;

public class ADSSAnitBot
{
    public static string SESSION_CAPTCHA = "CAPTCHA";
    const int default_width = 135;
    const int default_height = 40;
    protected Bitmap result = null;
    public int Width, Height;
    Random rnd;

    public ADSSAnitBot()
    {
        InitBitmap(default_width, default_height);
        rnd = new Random();
    }
    public ADSSAnitBot(int width, int height)
    {
        InitBitmap(default_width, default_height);
    }
    protected void InitBitmap(int width, int height)
    {
        result = new Bitmap(width, height);
        Width = width;
        Height = height;
        rnd = new Random();
    }
    public PointF Noise(PointF p, double eps)
    {
        p.X = Convert.ToSingle(rnd.NextDouble() * eps * 2 - eps) + p.X;
        p.Y = Convert.ToSingle(rnd.NextDouble() * eps * 2 - eps) + p.Y;
        return p;
    }
    public PointF Wave(PointF p, double amp, double size)
    {
        p.X = Convert.ToSingle(Math.Sin(p.X / size) * amp) + p.X;
        p.Y = Convert.ToSingle(Math.Sin(p.Y / size) * amp) + p.Y;
        return p;
    }
    public GraphicsPath RandomWarp(GraphicsPath path)
    {
        int PsCount = 10;
        PointF[] curvePs = new PointF[PsCount * 2];
        for (int u = 0; u < PsCount; u++)
        {
            curvePs[u].X = u * (Width / PsCount);
            curvePs[u].Y = Height / 2;
        }
        for (int u = PsCount; u < (PsCount * 2); u++)
        {
            curvePs[u].X = (u - PsCount) * (Width / PsCount);
            curvePs[u].Y = Height / 2 + 2;
        }
        path.AddLines(curvePs);
        double eps = Height * 0.05;
        double amp = rnd.NextDouble() * (double)(Height / 3);
        double size = rnd.NextDouble() * (double)(Width / 4) + Width / 8;
        double offset = (double)(Height / 3);
        PointF[] pn = new PointF[path.PointCount];
        byte[] pt = new byte[path.PointCount];
        GraphicsPath np2 = new GraphicsPath();
        GraphicsPathIterator iter = new GraphicsPathIterator(path);
        for (int i = 0; i < iter.SubpathCount; i++)
        {
            GraphicsPath sp = new GraphicsPath();
            bool closed;
            iter.NextSubpath(sp, out closed);
            Matrix m = new Matrix();
            m.RotateAt(Convert.ToSingle(rnd.NextDouble() * 30 - 15), sp.PathPoints[0]);
            m.Translate(-1 * i, 0);
            sp.Transform(m);
            np2.AddPath(sp, true);
        }
        for (int i = 0; i < np2.PointCount; i++)
        {
            pn[i] = Wave(np2.PathPoints[i], amp, size);
            pt[i] = np2.PathTypes[i];
        }
        GraphicsPath newpath = new GraphicsPath(pn, pt);
        return newpath;
    }
    public string DrawNumbers(int len)
    {
        string str = string.Empty;
        for (int i = 0; i < len; i++)
        {
            int n = rnd.Next() % 10;
            str += n.ToString();
        }
        DrawText(str);
        return str;
    }
    public void DrawText(string aText)
    {
        Graphics g = Graphics.FromImage(result);
        int startsize = Height;
        Font f = new Font("Courier New", startsize, FontStyle.Bold, GraphicsUnit.Pixel);
        do
        {
            f = new Font("Verdana", startsize, GraphicsUnit.Pixel);
            startsize--;
        } while ((g.MeasureString(aText, f).Width >= Width) || (g.MeasureString(aText, f).Height >= Height));
        SizeF sf = g.MeasureString(aText, f);
        int width = Convert.ToInt32(sf.Width);
        int height = Convert.ToInt32(sf.Height);
        int x = Convert.ToInt32(Math.Abs((double)width - (double)Width) * rnd.NextDouble());
        int y = Convert.ToInt32(Math.Abs((double)height - (double)Height) * rnd.NextDouble());
        GraphicsPath path = new GraphicsPath(FillMode.Alternate);
        FontFamily family = new FontFamily("Verdana");
        int fontstyle = (int)(FontStyle.Regular);
        float emSize = f.Size;
        Point origin = new Point(x, y);
        StringFormat frmt = StringFormat.GenericDefault;
        path.AddString(aText, family, fontstyle, emSize, origin, frmt);
        path = RandomWarp(path);
        g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
        Rectangle rect = new Rectangle(0, 0, Width, Height);
        g.FillRectangle(new System.Drawing.Drawing2D.LinearGradientBrush(rect, Color.White, Color.LightGray, 0f), rect);
        g.SmoothingMode = SmoothingMode.AntiAlias;
        g.FillPath(new SolidBrush(Color.Black), path);
        g.Dispose();
    }
    public Bitmap Result
    {
        get
        {
            return result;
        }
    }
}
